﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using TMV.Core.CM;
using TMV.DTO;
using TMV.DTO.Authorization;
using TMV.DTO.Tr;
using TMV.DTO.ModelData;
using Furion.LinqBuilder;
using TMV.DTO.Users;
using NPOI.SS.Formula.Functions;
using Microsoft.Extensions.Logging;
using StackExchange.Profiling.Internal;
using Org.BouncyCastle.Asn1.X509;
using System.Drawing.Printing;
using NPOI.Util;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Furion.Templates;
using System.Runtime.ConstrainedExecution;
using System.Security.Cryptography;
using TMV.DTO.TransportPlan;

namespace TMV.Application.Tr.Services
{
	public class TrServiceDM : ITrServiceDM, IDynamicApiController, ITransient
	{
		ISqlSugarClient c;
		private readonly ILogger<TrService> _logger;
		public TrServiceDM(ISqlSugarClient db, ILogger<TrService> logger)
		{
			_logger = logger;
			c = db;
		}

		#region 物流基础数据处理 
		public ResultEntity<bool> AddTransportationRecords(TransportationRecordsModel model)
		{
			TMV_Car car = c.Queryable<TMV_Car>().Where(w => w.PlateNumber == model.PlateNumber).First();
			if (car == null)
			{
				return new ResultEntityUtil<bool>().Failure("车牌号不存在！");
			}
			TMV_TransportPlan tp = c.Queryable<TMV_TransportPlan>().Where(w => w.MineCode == model.MineCode && w.AddTime.Date == DateTime.Now.Date).First();
			if (tp == null)
			{
				return new ResultEntityUtil<bool>().Failure("矿号不存在！");
			}

			TMV_TransportationRecords tr = new TMV_TransportationRecords();
			tr.Id = Guid.NewGuid();
			tr.State = 1;

			string ycode = "";
			do
			{
				ycode = "DT" + DateTime.Now.ToString("yyMMddHHmmssfff");
			} while (c.Queryable<TMV_TransportationRecords>().Where(n => n.Code == ycode).First() != null);
			tr.Code = ycode;

			tr.CarId = car.Id;
			tr.CollieryId = tp.Id;
			tr.RoughWeight = model.Weight;
			tr.ZScaleName = model.ScaleName;
			tr.ZScaleTime = DateTime.Now;
			tr.STime = DateTime.Now;
			tr.IsUpload = 1;
			tr.KouWeight = 0;


			var result = c.Insertable(tr).ExecuteCommand();
			if (result > 0)
			{
				return new ResultEntityUtil<bool>().Success(true);
			}
			else
			{
				return new ResultEntityUtil<bool>().Success(false);
			}
		}
		public ResultEntity<bool> UpTransportationRecords(TransportationRecordsModel model)
		{
			var data = c.Queryable<TMV_TransportationRecords>().InSingle(model.Id);
			if (data == null)
			{
				return new ResultEntityUtil<bool>().Failure("没找到物流订单！");
			}
			data.TareWeight = model.Weight;
			data.NetWeight = data.RoughWeight - model.Weight;
			data.QScaleName = model.ScaleName;
			data.QScaleTime = DateTime.Now;
			var result = c.Updateable(data).ExecuteCommand();
			if (result > 0)
			{
				return new ResultEntityUtil<bool>().Success(true);
			}
			else
			{
				return new ResultEntityUtil<bool>().Success(false);
			}
		}

		public ResultEntity<bool> DeTransportationRecords(Guid id)
		{
			throw new NotImplementedException();
		}

		public ResultPageEntity<TransportationRecordsDTO> GetTransportationRecordsList(Request_TransportationRecords dto)
		{
			var exp = Expressionable.Create<TMV_TransportationRecords>();
			if (!dto.STime.IsNullOrEmpty())
			{
				exp = exp.And(a => a.STime.Date >= DateTime.Parse(dto.STime).Date);
			}
			if (!dto.ETime.IsNullOrEmpty())
			{
				exp = exp.And(a => a.STime.Date <= DateTime.Parse(dto.ETime).Date);
			}
			if (!dto.Code.IsNullOrEmpty())
			{
				exp = exp.And(a => a.Code.Contains(dto.Code));
			}
			if (!dto.State.IsNullOrEmpty())
			{
				exp = exp.And(a => a.State == Convert.ToInt32(dto.State));
			}
			int count = 0;


			var query = c.Queryable<TMV_TransportationRecords, TMV_TransportPlan, TMV_Car>(
				(a, b, c) => new JoinQueryInfos(
				JoinType.Left, a.CollieryId == b.Id,
				JoinType.Left, a.CarId == c.Id)).OrderByDescending(a => a.STime)
				.Where(exp.ToExpression())
				.WhereIF(!dto.PlateNumber.IsNullOrEmpty(), (a, b, c) => c.PlateNumber == dto.PlateNumber)
				.WhereIF(!dto.MineCode.IsNullOrEmpty(), (a, b, c) => b.MineCode == dto.MineCode)
				.Select((a, b, c) => new TransportationRecordsDTO()
				{
					Id = a.Id,
					CarId = a.CarId,
					CollieryId = a.CollieryId,
					ETime = a.ETime,
					IsUpload = a.IsUpload,
					NetWeight = a.NetWeight,
					RoughWeight = a.RoughWeight,
					State = a.State,
					STime = a.STime,
					TareWeight = a.TareWeight,
					Code = a.Code,
					KouWeight = a.KouWeight,
					MineCode = b.MineCode,
					PlateNumber = c.PlateNumber,
					ZScaleName = a.ZScaleName,
					QScaleName = a.QScaleName,
					ZScaleTime = a.ZScaleTime,
					QScaleTime = a.QScaleTime, 
					CarType=c.Type,
				}).Mapper(x =>
						{
							//x.MineCode = c.Queryable<TMV_TransportPlan>().Where(w => w.Id == x.CollieryId).First().MineCode;
							//x.PlateNumber = c.Queryable<TMV_Car>().Where(w => w.Id == x.CarId).First().PlateNumber;
							x.ScalageRecordsData = c.Queryable<TMV_ScalageRecords>().Where(w => w.TId == x.Id).OrderBy(o => o.AddTime)
							.Select(xx => new ScalageRecordsDTO
							{ 
								AddTime = xx.AddTime,
								Id = xx.Id, 
								ProcessStatus = xx.ProcessStatus,
								TId = xx.TId }).ToList();
						})
				.ToPageList(dto.PageIndex, dto.PageSize, ref count);
			return new ResultPageEntity<TransportationRecordsDTO>() { Data = query, PageIndex = dto.PageIndex, PageSize = dto.PageSize, Count = count };
		}
		public TransportationRecordsDTO GetTransportationRecords(string PlateNumber)
		{
			var query = c.Queryable<TMV_TransportationRecords, TMV_TransportPlan, TMV_Car>((a, b, c) => a.CollieryId == b.Id && a.CarId == c.Id).Where((a, b, c) => a.STime.Date == DateTime.Now.Date && c.PlateNumber == PlateNumber).OrderByDescending(a => a.STime)
				.Select((a, b, c) => new TransportationRecordsDTO()
				{
					Id = a.Id,
					CarId = a.CarId,
					CollieryId = a.CollieryId,
					ETime = a.ETime,
					IsUpload = a.IsUpload,
					NetWeight = a.NetWeight,
					RoughWeight = a.RoughWeight,
					State = a.State,
					STime = a.STime,
					TareWeight = a.TareWeight,
					Code = a.Code,
					KouWeight = a.KouWeight,
					MineCode = b.MineCode,
					PlateNumber = c.PlateNumber,
					ZScaleName = a.ZScaleName,
					QScaleName = a.QScaleName,
					ZScaleTime = a.ZScaleTime,
					QScaleTime = a.QScaleTime,
				}).Mapper(x =>
				{
					x.MineCode = c.Queryable<TMV_TransportPlan>().Where(w => w.Id == x.CollieryId).First().MineCode;
					x.PlateNumber = c.Queryable<TMV_Car>().Where(w => w.Id == x.CarId).First().PlateNumber;

				}).First();
			return query;
		}

		public ResultEntity<bool> Qksc(int type, Guid Id)
		{
			var data = c.Queryable<TMV_TransportationRecords>().InSingle(Id);
			if (type == 1)
			{
				data.ZScaleName = null;
				data.RoughWeight = null;
				data.ZScaleTime = null;
			}
			else
			{
				data.TareWeight = null;
				data.NetWeight = null;
				data.QScaleName = null;
				data.QScaleTime = null;
			}

			var result = c.Updateable(data).ExecuteCommand();

			if (result > 0)
			{
				return new ResultEntityUtil<bool>().Success(true);
			}
			else
			{
				return new ResultEntityUtil<bool>().Success(false);
			}
		}


		#endregion

		#region 流程记录

		#endregion

		#region Scoket推送接口处理
		[AllowAnonymous]
		public ResultInfo GetDataInfo1(AuthorizationDTO dto)
		{

			TMV_Car car = c.Queryable<TMV_Car>().Where(w => w.PlateNumber == dto.PlateNumber).First();
			if (car == null)
			{
				return new ResultInfoUtil().Failure("1", "车牌号不存在！");
			}

			TMV_TransportPlan tp = c.Queryable<TMV_TransportPlan>().Where(w => w.MineCode == dto.CollieryCode && w.AddTime.Date == DateTime.Now.Date).First();
			if (tp == null)
			{
				return new ResultInfoUtil().Failure("1", "矿号-运输计划不存在！");
			}
			//int scaleNum = c.Queryable<TMV_Scale>().Where(w => w.Type == 1 && w.State == 1).Count();
			//List<DateTime> timeLi = c.Queryable<TMV_TransportationRecords>().OrderByDescending(px => px.STime).Take(scaleNum).Select(x => x.STime.Date).ToList();
			TMV_TransportationRecords tr = new TMV_TransportationRecords();
			tr.Id = Guid.NewGuid();
			tr.State = 1;


			TMV_TransportationRecords oldTr = c.Queryable<TMV_TransportationRecords>().Where(w => w.CarId == car.Id && w.CollieryId == tp.Id).First();
			if (oldTr != null)
			{
				#region 有上一趟数据


				if (oldTr.ETime == null && oldTr.TareWeight == null && oldTr.NetWeight == null)
				{
					#region 未记录皮重（未轻衡称重）
					return new ResultInfoUtil().Failure("1", "有上一趟数据/未轻衡称重：上一趟没有出厂怎么又进场绑卡了！");
					#endregion
				}
				else
				{
					#region 已记录皮重（已轻衡称重）
					TimeSpan ts = DateTime.Now - oldTr.STime;
					if (ts.Minutes < 60)
					{
						//一个小时内再次进厂告警
						tr.State = 2;
						TMV_AbnormalRecords ar = new TMV_AbnormalRecords();
						ar.Id = Guid.NewGuid();
						ar.TId = tr.Id;
						ar.AbnormalCause = "进场/出场时间报警";
						ar.AddTime = DateTime.Now;
						c.Insertable(ar).ExecuteCommand();
					}
					#endregion
				}
				#endregion
			}

			#region 绑卡操作 

			string ycode = "";
			do
			{
				ycode = "DT" + DateTime.Now.ToString("yyMMddHHmmssfff");
			} while (c.Queryable<TMV_TransportationRecords>().Where(n => n.Code == ycode).First() != null);
			tr.Code = ycode;

			tr.CarId = car.Id;
			tr.CollieryId = tp.Id;
			tr.RoughWeight = dto.Weight;
			tr.STime = DateTime.Now;
			tr.IsUpload = 1;
			tr.KouWeight = 0;

			c.Insertable(tr).ExecuteCommand();

			#endregion

			return new ResultInfoUtil().Success("绑卡完成！");
		}

		[AllowAnonymous]
		public ResultInfo GetDataInfo2(AuthorizationDTO dto)
		{
			#region 数据验证

			if (dto.Inside == 0)
			{
				return new ResultInfoUtil().Failure("1", "未正常停靠！");
			}
			if (dto.Finish == 0)
			{
				return new ResultInfoUtil().Failure("1", "未锁称！");
			}

			TMV_Car car = c.Queryable<TMV_Car>().Where(w => w.PlateNumber == dto.PlateNumber).First();
			if (car == null)
			{
				return new ResultInfoUtil().Failure("1", "车牌号不存在！");
			}
			TMV_Scale scale = c.Queryable<TMV_Scale>().Where(w => w.Name == dto.ClassName.ToString()).First();
			if (scale == null)
			{
				return new ResultInfoUtil().Failure("1", "衡不存在！");
			}
			TMV_TransportPlan tp = c.Queryable<TMV_TransportPlan>().Where(w => w.MineCode == dto.CollieryCode && w.AddTime.Date == DateTime.Now.Date).First();
			if (tp == null)
			{
				return new ResultInfoUtil().Failure("1", "矿号-运输计划不存在！");
			}
			#endregion

			TMV_TransportationRecords oldTr = c.Queryable<TMV_TransportationRecords>().Where(w => w.CarId == car.Id && w.CollieryId == tp.Id && w.ETime == null).First();
			if (oldTr != null)
			{
				#region 有上一趟数据

				TimeSpan ts = DateTime.Now - oldTr.STime;
				if (ts.Minutes < 3)
				{
					//3分钟内表示未采样 
					return new ResultInfoUtil().Failure("1", "未采样！");
				}
				if (oldTr.ZScaleName == null || oldTr.RoughWeight == null)
				{
					#region 未过重衡                        
					oldTr.RoughWeight = dto.Weight;
					oldTr.ZScaleName = scale.Name;
					oldTr.ZScaleTime = DateTime.Now;
					c.Updateable(oldTr).ExecuteCommand();

					return new ResultInfoUtil().Success("称重完成！");
					#endregion
				}
				else
				{
					if (oldTr.QScaleName == null || oldTr.TareWeight == null)
					{
						#region 未过轻衡或二次过重衡  -记录异常
						if (dto.Weight > (car.FullWeight + 10M))
						{
							#region 二次过重衡 
							oldTr.RoughWeight = dto.Weight;
							oldTr.ZScaleName = scale.Name;
							oldTr.ZScaleTime = DateTime.Now;

							oldTr.State = 2;
							TMV_AbnormalRecords ar = new TMV_AbnormalRecords();
							ar.Id = Guid.NewGuid();
							ar.TId = oldTr.Id;
							ar.AbnormalCause = "已记录毛重-重新过重衡";
							ar.AddTime = DateTime.Now;
							c.Insertable(ar).ExecuteCommand();

							return new ResultInfoUtil().Success("称重完成！");
							#endregion
						}
						#endregion
					}
					else
					{
						#region 已记录皮重和净重-重新称重-记录异常
						oldTr.State = 2;
						TMV_AbnormalRecords ar = new TMV_AbnormalRecords();
						ar.Id = Guid.NewGuid();
						ar.TId = oldTr.Id;
						ar.AbnormalCause = "已记录皮重和净重-重新过轻衡";
						ar.AddTime = DateTime.Now;
						c.Insertable(ar).ExecuteCommand();
						#endregion
					}
					#region 记录皮重和净重
					if (dto.Weight < car.EmptyWeight)
					{
						return new ResultInfoUtil().Failure("1", "皮重小于空水空油重量异常！");
					}
					if (dto.Weight > car.FullWeight)
					{
						return new ResultInfoUtil().Failure("1", "皮重大于满水满油重量异常！");
					}

					oldTr.TareWeight = dto.Weight;
					oldTr.NetWeight = oldTr.RoughWeight - dto.Weight;
					oldTr.QScaleName = scale.Name;
					oldTr.QScaleTime = DateTime.Now;
					c.Updateable(oldTr).ExecuteCommand();

					return new ResultInfoUtil().Success("称重完成！");
					#endregion
				}



				#endregion
			}
			else
			{
				#region 没有有上一趟数据
				return new ResultInfoUtil().Failure("1", "没有有绑卡！");
				#endregion
			}
			//return new ResultInfoUtil().Success(dto.ID,  "称重完成！");
		}

		[AllowAnonymous]
		public ResultInfo GetDataInfo3(AuthorizationDTO dto)
		{
			#region 数据验证 
			TMV_Car car = c.Queryable<TMV_Car>().Where(w => w.PlateNumber == dto.PlateNumber).First();
			if (car == null)
			{
				return new ResultInfoUtil().Failure("1", "车牌号不存在！");
			}
			TMV_Scale scale = c.Queryable<TMV_Scale>().Where(w => w.Name == dto.ClassName.ToString()).First();
			if (scale == null)
			{
				return new ResultInfoUtil().Failure("1", "衡不存在！");
			}
			TMV_TransportPlan tp = c.Queryable<TMV_TransportPlan>().Where(w => w.MineCode == dto.CollieryCode && w.AddTime.Date == DateTime.Now.Date).First();
			if (tp == null)
			{
				return new ResultInfoUtil().Failure("1", "矿号-运输计划不存在！");
			}
			#endregion

			TMV_TransportationRecords oldTr = c.Queryable<TMV_TransportationRecords>().Where(w => w.CarId == car.Id && w.CollieryId == tp.Id && w.ETime == null).First();
			if (oldTr != null)
			{
				#region 有上一趟数据
				oldTr.ETime = DateTime.Now;
				c.Updateable(oldTr).ExecuteCommand();
				#endregion
			}
			else
			{
				#region 没有有上一趟数据
				return new ResultInfoUtil().Failure("1", "没有运输记录！");
				#endregion
			}
			return new ResultInfoUtil().Success("出厂完成！");
		}

		[AllowAnonymous]
		public UploadDTO GetScData(AuthorizationDTO dto)
		{

			var li = c.Queryable<TMV_TransportationRecords, TMV_TransportPlan, TMV_Car>((a, b, c) => a.CollieryId == b.Id && a.CarId == c.Id)
				.Where((a, b, c) => a.IsUpload == 1 && a.ETime != null && c.PlateNumber == dto.PlateNumber && b.MineCode == dto.CollieryCode)
			   .OrderByDescending(a => a.STime)
			   .Select((a, b, c) => new UploadDTO()
			   {
				   Code = a.Code,
				   ID = 0,
				   CHEPH = c.PlateNumber,
				   PINZ = b.CargoName,
				   MEIKDW = b.MEIKDW,
				   GONGYS = b.GONGYS,
				   FAZ = "汽",
				   DAOZ = "汽",
				   MAOZ = Convert.ToInt32(a.RoughWeight),
				   PIZ = Convert.ToInt32(a.TareWeight),
				   FAHRQ = b.SendTime.ToString("yy-MM-dd"),
				   DAOHRQ = Convert.ToDateTime(b.ArrivalTime).ToString("yy-MM-dd"),
				   KOUJ = "市场采购",
				   YUNSFS = "公路",
				   JIANJFS = "过衡",
				   JINCJJY = "无人值守",
				   CHUCJJY = "无人值守",
				   JINCSJ = a.STime.ToString("yy-MM-dd HH:mm:ss"),
				   CHUCSJ = Convert.ToDateTime(a.ETime).ToString("yy-MM-dd HH:mm:ss"),
				   KOUZ = a.KouWeight,
				   JINCHH = a.ZScaleName,
				   CHUCHH = a.QScaleName,
				   CHENGYDW = b.Carrier,
				   CHEC = "",

			   })
				.First();

			return li;
		}

		[AllowAnonymous]
		public void UpScData(string Code)
		{
			var data = c.Queryable<TMV_TransportationRecords>().Where(w => w.Code == Code).First();

			data.IsUpload = 2;

			var result = c.Updateable(data).ExecuteCommand();
		}

		[AllowAnonymous]
		public PrintDto GetPrint(AuthorizationDTO dto)
		{
			var query = c.Queryable<TMV_TransportationRecords, TMV_TransportPlan, TMV_Car>((a, b, c) => a.CollieryId == b.Id && a.CarId == c.Id)
			   .Where((a, b, c) => a.IsUpload == 1 && a.ETime != null && c.PlateNumber == dto.PlateNumber && b.MineCode == dto.CollieryCode)
			   .OrderByDescending(a => a.STime)
				.Select((a, b, c) => new PrintDto()
				{
					unit = b.MEIKDW,
					scalenumber = a.ZScaleName + "-" + a.QScaleName,
					number = a.Code,
					shipper = b.SendUnit,
					consignee = b.ReceiptUnit,
					name = b.CargoName,
					carryunit = b.Carrier,
					specification = b.Specification,
					splatenumber = c.PlateNumber,
					roughweight = a.RoughWeight.ToString(),
					tareweight = a.TareWeight.ToString(),
					buckleweight = a.KouWeight.ToString(),
					netweight = a.NetWeight.ToString(),
					shipnumber = b.ShipCode.ToString(),
					truckscar = "",
					emptycar = "",
					trucktime = a.ZScaleTime.ToString(),
					lighttime = a.QScaleTime.ToString(),
					remark = "",

				}).First();
			return query;
		}

		public void AddScalageRecords(AuthorizationDTO dto)
		{
			#region 数据验证 
			TMV_Car car = c.Queryable<TMV_Car>().Where(w => w.PlateNumber == dto.PlateNumber).First();
			if (car == null)
			{
				return;
			}
			TMV_Scale scale = c.Queryable<TMV_Scale>().Where(w => w.Name == dto.ClassName.ToString()).First();
			if (scale == null)
			{
				return;
			}
			TMV_TransportPlan tp = c.Queryable<TMV_TransportPlan>().Where(w => w.MineCode == dto.CollieryCode && w.AddTime.Date == DateTime.Now.Date).First();
			if (tp == null)
			{
				return;
			}
			#endregion

			TMV_TransportationRecords oldTr = c.Queryable<TMV_TransportationRecords>().Where(w => w.CarId == car.Id && w.CollieryId == tp.Id && w.ETime == null).First();
			if (oldTr != null)
			{
				#region 有上一趟数据
				TMV_ScalageRecords tr = new TMV_ScalageRecords();
				tr.Id = Guid.NewGuid();
				tr.AddTime = DateTime.Now;
				tr.ProcessStatus = dto.ProcessStatus;
				tr.TId = oldTr.Id;

				c.Insertable(tr).ExecuteCommand();
				#endregion
			}
		}
		#endregion


	}
}
